
const { ccclass, property } = cc._decorator;

@ccclass
export class VisualJoyStick extends cc.Component {

  @property({ type: cc.Node, tooltip: '操控杆的控制点' })
  controlDot: cc.Node = null;
  @property({ type: cc.Node, tooltip: '操控杆' })
  joystick: cc.Node = null;


  // @property({ type: cc.Node, tooltip: '决定摇杆位置的触摸层' })
  // topTouchLayer: cc.Node = null;

  @property({
    type: cc.Component.EventHandler
  }) changeEvents: cc.Component.EventHandler[] = []

  movableFlag: boolean = false;
  radian: number = 0;
  speed: number = 150;

  radius: number = 0;
  onLoad() {
    this.radius = this.node.width / 2 - this.controlDot.width / 2;

    this.initTouchEvent();
  }

  initTouchEvent() {

    
    this.node.on(cc.Node.EventType.TOUCH_START, this.touchStartEvent, this);
    this.node.on(cc.Node.EventType.TOUCH_MOVE, this.touchMoveEvent, this);
    this.node.on(cc.Node.EventType.TOUCH_END, this.touchEndEvent, this);
    this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.touchEndEvent, this);
  }

  touchStartEvent(evt: cc.Event.EventTouch) {
    const tempPosVec3 = new cc.Vec3(evt.getLocation().x, evt.getLocation().y, 0);
    let touchPos: cc.Vec3 = this.node.convertToNodeSpaceAR(tempPosVec3);
    const distance = touchPos.mag();

    // 以x轴正方向为基准，计算偏移量
    const tempPosVec2 = new cc.Vec2(touchPos.x, touchPos.y);
    this.radian = new cc.Vec2(1, 0).signAngle(tempPosVec2);
    const offsetX = Math.cos(this.radian) * this.radius;
    const offsetY = Math.sin(this.radian) * this.radius;
    this.setDotPosition(this.radius > distance ? touchPos : new cc.Vec3(offsetX, offsetY, 0));

    this.movableFlag = true;
  }

  touchMoveEvent(evt: cc.Event.EventTouch) {


    const tempPosVec3 = new cc.Vec3(evt.getLocation().x, evt.getLocation().y, 0);
    let touchPos: cc.Vec3 = this.node.convertToNodeSpaceAR(tempPosVec3);
    const distance = touchPos.mag();

    const tempPosVec2 = new cc.Vec2(touchPos.x, touchPos.y);
    this.radian = new cc.Vec2(1, 0).signAngle(tempPosVec2);
    const offsetX = Math.cos(this.radian) * this.radius;
    const offsetY = Math.sin(this.radian) * this.radius;
    this.setDotPosition(this.radius > distance ? touchPos : new cc.Vec3(offsetX, offsetY, 0))
  }

  touchEndEvent() {
    this.movableFlag = false;
    this.setDotPosition(cc.Vec3.ZERO);
  }

  direction: cc.Vec3 = new cc.Vec3()
  setDotPosition(pos: cc.Vec3) {
    this.controlDot.setPosition(pos);
    this.direction.set(cc.v3(pos.x / this.radius, pos.y / this.radius, 0))

    /**返回方向向量和弧度 */
    cc.Component.EventHandler.emitEvents(this.changeEvents, this, { direction: this.direction, radian: this.radian })

  }

}
